package com.bah.tract.client.ui;

import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;

import com.bah.tract.client.WorkLog;
import com.bah.tract.service.Task;
import com.bah.tract.service.Work;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.toedter.calendar.JDateChooser;

@Singleton
public class TimeCardDialog extends JDialog implements DataDialog {

	private final TimeCardPanel panel;

	private final MouseListener mouseListener;

	@Override
	public final void setVisible(final boolean b) {
		// Refresh the data in the panel if it is being displayed
		if (b) {
			refresh();
		}
		super.setVisible(b);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.bah.tract.client.ui.TimeCardDialog#refresh()
	 */
	@Override
	public final void refresh() {
		panel.refresh(true);
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private final WorkLog workLog;

	private final LabelService labelService;

	@Inject
	public TimeCardDialog(@Named("defaultImage") final Image image,
			final WorkLog workLog,
			@Named("timeCardListener") final MouseListener mouseListener,
			final LabelService labelService) {
		this.labelService = labelService;
		setTitle("TRACT - Time Cards");
		this.mouseListener = mouseListener;
		panel = new TimeCardPanel();
		this.workLog = workLog;
		setIconImage(image);
		add(panel);
		pack();
	}

	public class TimeCardPanel extends javax.swing.JPanel {

		public TimeCardPanel() {
			initComponents();
		}

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		/**
		 * This method is called from within the constructor to initialize the
		 * form. WARNING: Do NOT modify this code. The content of this method is
		 * always regenerated by the Form Editor.
		 */
		// <editor-fold defaultstate="collapsed" desc="Generated Code">
		private void initComponents() {

			jLabel1 = new javax.swing.JLabel();
			datePicker = new JDateChooser();
			jTabbedPane1 = new javax.swing.JTabbedPane();

			jButton2 = new javax.swing.JButton();

			jButton2.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(final ActionEvent e) {
					TimeCardDialog.this.setVisible(false);
				}
			});

			setName("Form"); // NOI18N

			final ResourceBundle resourceMap = ResourceBundle
					.getBundle("com.bah.tract.client.ui.TimeCard");
			jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
			jLabel1.setName("jLabel1"); // NOI18N
			final Date date = new Date();
			datePicker.setDate(date);
			datePicker.setName("jTextField1"); // NOI18N
			datePicker.getDateEditor().addPropertyChangeListener(
					new PropertyChangeListener() {
						@Override
						public void propertyChange(final PropertyChangeEvent e) {
							if ("date".equals(e.getPropertyName())) {
								refresh(false);
							}
						}
					});

			jButton2.setText(resourceMap.getString("jButton2.text")); // NOI18N
			jButton2.setName("jButton2"); // NOI18N

			final javax.swing.GroupLayout layout = new javax.swing.GroupLayout(
					this);
			setLayout(layout);
			layout.setHorizontalGroup(layout
					.createParallelGroup(
							javax.swing.GroupLayout.Alignment.LEADING)
					.addGroup(
							layout.createSequentialGroup()
									.addContainerGap()
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.TRAILING)
													.addComponent(
															jTabbedPane1,
															javax.swing.GroupLayout.Alignment.LEADING,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															693,
															Short.MAX_VALUE)
													.addGroup(
															javax.swing.GroupLayout.Alignment.LEADING,
															layout.createSequentialGroup()
																	.addComponent(
																			jLabel1)
																	.addPreferredGap(
																			javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
																	.addComponent(
																			datePicker,
																			javax.swing.GroupLayout.PREFERRED_SIZE,
																			107,
																			javax.swing.GroupLayout.PREFERRED_SIZE)
																	.addPreferredGap(
																			javax.swing.LayoutStyle.ComponentPlacement.RELATED,
																			504,
																			Short.MAX_VALUE)
																	.addComponent(
																			jButton2)))
									.addContainerGap()));
			layout.setVerticalGroup(layout
					.createParallelGroup(
							javax.swing.GroupLayout.Alignment.LEADING)
					.addGroup(
							layout.createSequentialGroup()
									.addContainerGap()
									.addGroup(
											layout.createParallelGroup(
													javax.swing.GroupLayout.Alignment.BASELINE)
													.addComponent(jLabel1)
													.addComponent(
															datePicker,
															javax.swing.GroupLayout.PREFERRED_SIZE,
															javax.swing.GroupLayout.DEFAULT_SIZE,
															javax.swing.GroupLayout.PREFERRED_SIZE))
									.addGap(18, 18, 18)
									.addComponent(
											jTabbedPane1,
											javax.swing.GroupLayout.DEFAULT_SIZE,
											360, Short.MAX_VALUE)
									.addGap(18, 18, 18).addComponent(jButton2)
									.addContainerGap()));
		}// </editor-fold>

		// Variables declaration - do not modify
		private javax.swing.JButton jButton2;
		private javax.swing.JLabel jLabel1;
		private javax.swing.JTabbedPane jTabbedPane1;
		private JDateChooser datePicker;

		private Comparator<TimeCardRow> rowSort = new TimeCardRowSorter();

		// End of variables declaration

		public void refresh(final boolean updateDate) {
			if (updateDate) {
				datePicker.setDate(new Date());
			}
			final Collection<Work> daysWork = workLog.getDaysWork(datePicker
					.getDate());
			final Map<Long, SortedSet<TimeCardRow>> stores = new HashMap<Long, SortedSet<TimeCardRow>>();

			for (final Work work : daysWork) {

				for (final Task task : work.getTasks()) {

					SortedSet<TimeCardRow> table;
					if (stores.containsKey(task.getStoreId())) {
						table = stores.get(task.getStoreId());
					} else {
						table = new TreeSet<TimeCardRow>(rowSort);
						stores.put(task.getStoreId(), table);
					}
					final TimeCardRow row = new TimeCardRow(work, task,
							labelService);
					table.add(row);
				}
			}
			jTabbedPane1.removeAll();
			for (final Map.Entry<Long, SortedSet<TimeCardRow>> entry : stores
					.entrySet()) {
				final JScrollPane jScrollPane = new javax.swing.JScrollPane();
				final JTable jTable = new javax.swing.JTable();
				jTabbedPane1.setName("jTabbedPane1"); // NOI18N

				jScrollPane.setName("jScrollPane1"); // NOI18N
				// wrap the sorted set in a list to allow access by row index
				jTable.setModel(new TimeCardTableModel(
						new ArrayList<TimeCardRow>(entry.getValue())));
				jTable.addMouseListener(mouseListener);
				jTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
				jTable.setName("jTable1"); // NOI18N
				jScrollPane.setViewportView(jTable);

				jTabbedPane1.addTab(
						labelService.getWorkStoreLabel(entry.getKey(), entry
								.getValue().first().getWork().getProjectId()),
						jScrollPane); // NOI18N
			}
		}
	}

}
